package fr.snac.bm;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.tumblr.jumblr.JumblrClient;
import com.tumblr.jumblr.types.Photo;
import com.tumblr.jumblr.types.PhotoPost;
import com.tumblr.jumblr.types.PhotoSize;
import com.tumblr.jumblr.types.Post;

import fr.snac.serialization.Infos;
import fr.snac.serialization.InfosDeserializer;
import fr.snac.serialization.InfosSerializer;
import fr.snac.serialization.PostInfo;
import fr.snac.utils.Constants;
import fr.snac.utils.DateUtil;
import fr.snac.utils.FilesUtil;
import fr.snac.utils.PhotoUtil;
import fr.snac.utils.TumblrClient;

public class AsyncPhoto extends AsyncTask<Void, Void, IOException>{

	volatile BonjourActivity activity;

	boolean alreadyDownloaded = false;
	boolean noNetwork = false;
	boolean savedImagesMode = true;

	long postId;
	String imageDate;
	
	AsyncSearch asyncSearch;
	Bitmap madameBitmap;
	Infos infos;
	InfosDeserializer deSerializer;
	PhotoPost photoPost;
	SharedPreferences settings;
	Uri madameUri;

	/** View elements **/
	ImageView madameImage;
	MenuItem menuFavourite;
	MenuItem menuWallpaper;
	ProgressBar progressBar;
	TextView day;
	TextView proposer;
	TextView processingInfo;
	TextView useInfo;
	

	public AsyncPhoto(BonjourActivity activity, AsyncSearch asyncSearch, String imageDate, long postId){
		this.activity = activity;
		this.asyncSearch = asyncSearch;
		this.imageDate = imageDate;
		this.postId = postId;
		this.settings = activity.getSharedPreferences(Constants.SETTINGS_PREFERENCES, 0);
	}


	@Override
	public void onPreExecute(){

		LayoutInflater li = LayoutInflater.from(activity);
		RelativeLayout rl = (RelativeLayout)li.inflate(R.layout.madame_layout, null);
		rl.setTag(imageDate);

		day = (TextView)rl.findViewById(R.id.day);
		proposer = (TextView)rl.findViewById(R.id.proposer);
		processingInfo = (TextView)rl.findViewById(R.id.processingInfo);
		useInfo = (TextView)rl.findViewById(R.id.useInfo);
		madameImage = (ImageView)rl.findViewById(R.id.madameImage);
		progressBar = (ProgressBar)rl.findViewById(R.id.progressBar);

		if (savedImagesMode == false || !FilesUtil.imageAlreadyDownloaded(imageDate)){
			day.setVisibility(View.GONE);
			proposer.setVisibility(View.GONE);
			madameImage.setVisibility(View.GONE);
			progressBar.setVisibility(View.VISIBLE);
			processingInfo.setVisibility(View.VISIBLE);
			useInfo.setVisibility(View.VISIBLE);	
		}

		int index = activity.getAddingIndex(imageDate);
		
		ViewFlipper flipper = activity.flipper;

		if (!activity.isInFlipper(imageDate)){
			
			menuFavourite = activity.menuFavourite;
			menuWallpaper = activity.menuWallpaper;
			
			if (menuFavourite != null && menuWallpaper != null){
				menuFavourite.setEnabled(false);
				menuWallpaper.setEnabled(false);
			}

			if (activity.direction.equals(Constants.DIRECTION_NEXT)){
				
				flipper.addView(rl, index);
				flipper.setInAnimation(activity, R.anim.in_left);
				flipper.setOutAnimation(activity, R.anim.out_left);			
				flipper.setDisplayedChild(index);

				if (activity.flag.equals(Constants.FLAG_FROM_SEARCH)){
					int count = flipper.getChildCount();
					String lastFlipperDate = flipper.getChildAt(count - 1).getTag().toString();
					if (DateUtil.daysBetweenDate(imageDate, lastFlipperDate) > Constants.MAX_IMAGES_IN_FLIPPER)
						flipper.removeViews(0, count - 1);
				}
				
				activity.removeExtraViews();				
			}else if (activity.direction.equals(Constants.DIRECTION_PREV)){				
				
				flipper.addView(rl, index);
				flipper.setInAnimation(activity, R.anim.in_right);
				flipper.setOutAnimation(activity, R.anim.out_right);
				flipper.setDisplayedChild(index);
				
				
				if (activity.flag.equals(Constants.FLAG_FROM_SEARCH)){
					int count = flipper.getChildCount();
					String lastFlipperDate = flipper.getChildAt(count - 1).getTag().toString();
					if (DateUtil.daysBetweenDate(imageDate, lastFlipperDate) > Constants.MAX_IMAGES_IN_FLIPPER)
						flipper.removeViews(1, count - 1);
				}
				
				activity.removeExtraViews();
			}else{
				flipper.addView(rl);
			}
			
			
			
		}else{
			if (activity.direction.equals(Constants.DIRECTION_NEXT)){

				flipper.setInAnimation(activity, R.anim.in_left);
				flipper.setOutAnimation(activity, R.anim.out_left);
				flipper.setDisplayedChild(index);
			}else if (activity.direction.equals(Constants.DIRECTION_PREV)){
				flipper.setInAnimation(activity, R.anim.in_right);
				flipper.setOutAnimation(activity, R.anim.out_right);
				flipper.setDisplayedChild(index);
			}
		}
		
		activity.flag = Constants.FLAG_NO_FLAG;
	}

	@Override
	protected IOException doInBackground(Void... arg) {

		savedImagesMode = settings.getBoolean(Constants.SETTINGS_PHOTO_SAVED, true);
		deSerializer = new InfosDeserializer();
		infos = deSerializer.getInfos();

		if (savedImagesMode == true && FilesUtil.imageAlreadyDownloaded(imageDate)){
			alreadyDownloaded = true;

			File image = new File(FilesUtil.getImageFolderPath() + "/" + imageDate + FilesUtil.getImageType(imageDate));

			madameUri = Uri.fromFile(image);
			image = null; 

			try {
				madameBitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), madameUri);				
			}catch (IOException e) {
				return e;
			}

			return null;
		}


		ConnectivityManager manager = (ConnectivityManager)activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo network = manager.getActiveNetworkInfo();

		if (network == null || !network.isConnected() || !network.isAvailable()) {

			if (infos == null || infos.size() == 0){
				noNetwork = true;
				return null;
			}
			
			File image = new File(FilesUtil.getImageFolderPath() + "/" + imageDate + FilesUtil.getImageType(imageDate));

			madameUri = Uri.fromFile(image);

			image = null;

			try {
				madameBitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), madameUri);				
			}catch (IOException e) {
				return e;
			}

			alreadyDownloaded = true;

			return null;
		}

		JumblrClient client = TumblrClient.initializeClient();

		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("type", "photo");
		queryParams.put("id", postId);
		queryParams.put("limit", 1);

		List<Post> posts = client.blogPosts(Constants.BLOG_ADDRESS, queryParams);

		Post p = posts.get(0);

		photoPost = (PhotoPost)p;
		List<Photo> photos = photoPost.getPhotos();
		Photo photo = photos.get(0);
		List<PhotoSize> sizes = photo.getSizes();

		DisplayMetrics metrics = new DisplayMetrics(); 
		activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

		PhotoSize madamePhotoSize = PhotoUtil.getMoreAdaptedPhoto(sizes, metrics);
		String USName = DateUtil.getUSDate(photoPost.getDateGMT());
		
		URL url;
		try {
			url = new URL(madamePhotoSize.getUrl());
			InputStream is = url.openConnection().getInputStream();
			madameBitmap = BitmapFactory.decodeStream(is);

			is.close();

			if (savedImagesMode){
				PhotoUtil.saveBitmapImage(madameBitmap, USName);
				FilesUtil.keepLastMadames(settings);
				if (FilesUtil.isInfosFileCreated()){
					if (deSerializer.deSerialize()){
						infos = deSerializer.getInfos();
						String dateToCheck = DateUtil.getUSDate(photoPost.getDateGMT());
						PostInfo pi = new PostInfo(photoPost.getId(), photoPost.getCaption(), dateToCheck);

						infos.put(imageDate, pi);

						InfosSerializer serializer = new InfosSerializer(infos);
						serializer.serialize();
					}
				}
			}
		}catch (IOException e) {
			return e;
		}

		return null;		
	}
	
	@Override
	protected void onPostExecute(IOException result){

		BonjourActivity activity = this.activity;
		String title;

		asyncSearch.asyncPhoto = null;
		
		if (noNetwork){
			day.setVisibility(View.GONE);
			proposer.setVisibility(View.GONE);
			madameImage.setVisibility(View.GONE);
			progressBar.setVisibility(View.GONE);
			useInfo.setVisibility(View.GONE);
			
			processingInfo.setVisibility(View.VISIBLE);
			
			Resources r = activity.getResources();
			
			processingInfo.setText(r.getString(R.string.noConnexionText));
			processingInfo.setTextSize(16);
			
			activity.swipeEnabled = false;
			
			return;
		}
		
		day.setVisibility(View.VISIBLE);
		proposer.setVisibility(View.VISIBLE);
		madameImage.setVisibility(View.VISIBLE);
		progressBar.setVisibility(View.GONE);
		processingInfo.setVisibility(View.GONE);
		useInfo.setVisibility(View.GONE);

		madameImage.setImageBitmap(madameBitmap);
		madameBitmap = null;

		if (alreadyDownloaded){

			deSerializer = new InfosDeserializer();
			deSerializer.deSerialize();

			Infos infos = deSerializer.getInfos();
			PostInfo pi = infos.get(imageDate);

			title = DateUtil.translateDateIntoFrench(pi.getDate());		
			day.setText(title);
			proposer.setText(Jsoup.parse(pi.getCaption()).text());
		}else{
			title = DateUtil.translateDateIntoFrench(photoPost.getDateGMT());

			day.setText(title);
			proposer.setText(Jsoup.parse(photoPost.getCaption()).text());
			
			
		}
		
		if (menuFavourite != null && menuWallpaper != null){
			menuFavourite.setEnabled(true);
			menuWallpaper.setEnabled(true);
		}
		
		if (activity.isCurrentFavourite()){
			if (menuFavourite != null){
				menuFavourite.setIcon(android.R.drawable.star_on);
				menuFavourite.setEnabled(false);	
			}
		}
		else{
			if (menuFavourite != null){
				menuFavourite.setIcon(android.R.drawable.star_off);
				menuFavourite.setEnabled(true);
			}
		}

		activity.currentDate = imageDate;
		activity.setShareIntent(activity.buildShareIntent());

		if (result != null){
			Toast.makeText(activity, result.getMessage(), Toast.LENGTH_SHORT).show();
		}
	}
}
